
package utils;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageInstaller.Session;
import android.content.pm.PackageInstaller.SessionCallback;
import android.content.pm.PackageInstaller.SessionParams;
import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


public class PackageUtils {
    private static PackageUtils instance;

    public PackageUtils() {
    }

    public static PackageUtils get() {
        if (instance == null) {
            Class var0 = PackageUtils.class;
            synchronized (PackageUtils.class) {
                if (instance == null) {
                    instance = new PackageUtils();
                }
            }
        }

        return instance;
    }
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void install(Context context, String apkFilePath) {
        PackageManager packageManager = context.getPackageManager();
        File apkFile = new File(apkFilePath);
        PackageInstaller packageInstaller = packageManager.getPackageInstaller();
        SessionParams sessionParams = new SessionParams(1);
        sessionParams.setSize(apkFile.length());
        int sessionId = this.createSession(packageInstaller, sessionParams);
        packageInstaller.registerSessionCallback(new PackageUtils.InstallSessionCallback(sessionId));
        if (sessionId != -1) {
            boolean copySuccess = this.copyInstallFile(packageInstaller, sessionId, apkFilePath);
            if (copySuccess) {
                this.execInstallCommand(context, packageInstaller, sessionId);
            }
        }

    }
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void uninstall(Context context, String packageName) {
        MyUtil.showLog("PackageUtils", packageName);
        Intent broadcastIntent = new Intent(context, this.getClass());
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, broadcastIntent, 134217728);
        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
        packageInstaller.uninstall(packageName, pendingIntent.getIntentSender());
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private int createSession(PackageInstaller packageInstaller, SessionParams sessionParams) {
        int sessionId = -1;

        try {
            sessionId = packageInstaller.createSession(sessionParams);
        } catch (IOException var5) {
            var5.printStackTrace();
        }

        return sessionId;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private boolean copyInstallFile(PackageInstaller packageInstaller, int sessionId, String apkFilePath) {
        InputStream in = null;
        OutputStream out = null;
        Session session = null;
        boolean success = false;

        try {
            File apkFile = new File(apkFilePath);
            session = packageInstaller.openSession(sessionId);
            out = session.openWrite("base.apk", 0L, apkFile.length());
            in = new FileInputStream(apkFile);
            int total = 0;
            byte[] buffer = new byte[65536];

            int c;
            while ((c = in.read(buffer)) != -1) {
                total += c;
                out.write(buffer, 0, c);
            }

            session.fsync(out);
            success = true;
        } catch (IOException var15) {
            var15.printStackTrace();
        } finally {
            this.closeQuietly(out);
            this.closeQuietly(in);
            this.closeQuietly(session);
        }

        return success;
    }
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void execInstallCommand(Context context, PackageInstaller packageInstaller, int sessionId) {
        Session session = null;

        try {
            session = packageInstaller.openSession(sessionId);
            Intent intent = new Intent(context, this.getClass());
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, 134217728);
            session.commit(pendingIntent.getIntentSender());
        } catch (IOException var10) {
            var10.printStackTrace();
        } finally {
            this.closeQuietly(session);
        }

    }

    private void closeQuietly(Closeable c) {
        if (c != null) {
            try {
                c.close();
            } catch (IOException var3) {
                var3.printStackTrace();
            }
        }

    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public class InstallSessionCallback extends SessionCallback {
        private int mSessionId = -1;

        public InstallSessionCallback(int mSessionId) {
            this.mSessionId = mSessionId;
        }

        public void onCreated(int sessionId) {
            Log.e("apk install", "onCreated()");
        }

        public void onBadgingChanged(int sessionId) {
            Log.e("apk install", "onBadgingChanged()");
        }

        public void onActiveChanged(int sessionId, boolean active) {
            Log.e("apk install", "onActiveChanged()");
        }

        public void onProgressChanged(int sessionId, float progress) {
            if (sessionId == this.mSessionId) {
                Log.e("apk install", progress + "");
            }

        }

        public void onFinished(int sessionId, boolean success) {
            if (this.mSessionId == sessionId) {
                if (success) {
                    Log.e("apk install", "onFinished() SUCCESS");
                } else {
                    Log.e("apk install", "onFinished() Fail");
                }
            }

        }
    }
}